package com.toubutu.audio.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.toubutu.audio.admin.dto.PermissionDto;
import com.toubutu.audio.admin.dto.RoleBindPermissionVo;
import com.toubutu.audio.admin.entity.Permission;
import com.toubutu.audio.admin.mapper.PermissionMapper;
import com.toubutu.audio.admin.service.PermissionService;
import com.toubutu.audio.admin.service.RolePermissionService;
import com.toubutu.audio.admin.vo.PermissionVo;
import com.toubutu.common.BusinessException;
import com.toubutu.common.StatusCodeEnum;
import com.toubutu.constants.BaseConstants;

import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 权限服务实现类
 * @author 戒燥
 * @since 2023-09-30
 */
@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements PermissionService {

    @Resource
    private RolePermissionService rolePermissionService;

    @Override
    public List<RoleBindPermissionVo> getMenuForRoleBindTree() {
        LambdaQueryWrapper<Permission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Permission::getIsDelete, BaseConstants.UN_DELETED);
        List<Permission> allPermissions = list(wrapper);
        return buildRoleMenuTree(allPermissions,BaseConstants.PARENT_MENU_ID);
    }

    @Override
    public List<PermissionVo> getPermissionTree() {
        LambdaQueryWrapper<Permission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Permission::getIsDelete, BaseConstants.UN_DELETED);
        List<Permission> allPermissions = list(wrapper);
        return buildMenuTree(allPermissions,BaseConstants.PARENT_MENU_ID);
    }



    @Override
    public PermissionVo getPermissionInfo(Integer menuId) {
        LambdaQueryWrapper<Permission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Permission::getId,menuId).eq(Permission::getIsDelete,BaseConstants.UN_DELETED);
        Permission permission = this.getOne(wrapper);
        PermissionVo permissionVo = new PermissionVo();
        BeanUtils.copyProperties(permission, permissionVo);
        return permissionVo;
    }

    @Override
    public Boolean addPermission(PermissionDto permissionDto) {
        LambdaQueryWrapper<Permission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Permission::getIsDelete,BaseConstants.UN_DELETED)
                .and(w->w.eq(Permission::getName, permissionDto.getName()).or().eq(Permission::getCode, permissionDto.getCode()));
        Permission permission = this.getOne(wrapper);
        if (permission !=null){
            throw new BusinessException(StatusCodeEnum.USER_HANDLE.getCode(),"权限名称/权限标识已存在!!");
        }
        return save(permissionDto.toPo());
    }

    @Override
    public Boolean updatePermission(PermissionDto permissionDto) {
        Permission permission = new Permission();
        BeanUtils.copyProperties(permissionDto, permission);
        return updateById(permission);
    }

    @Override
    public Boolean deletePermission(Integer permissionId) {
        LambdaQueryWrapper<Permission> permissionWrapper = new LambdaQueryWrapper<>();
        permissionWrapper.eq(Permission::getIsDelete,BaseConstants.UN_DELETED)
                .eq(Permission::getId,permissionId);
        Permission permission = getOne(permissionWrapper);
        if (permission ==null){return false;}
        List<Integer> roleMenuIds=new ArrayList<>();
        roleMenuIds.add(permissionId);
        if (permission.getParentId().equals(BaseConstants.PARENT_MENU_ID)){
            //查询当前权限下的子权限
            permissionWrapper.clear();
            permissionWrapper.eq(Permission::getIsDelete,BaseConstants.UN_DELETED)
                    .eq(Permission::getParentId, permission.getId());
            List<Permission> childPermissionList = list(permissionWrapper);
            if (childPermissionList.size()>0){
                //获取所有子权限id
                roleMenuIds.addAll(childPermissionList.stream().map(Permission::getId).collect(Collectors.toList()));
            }
        }
        //删除权限
        LambdaUpdateWrapper<Permission> updateMenuWrapper = new LambdaUpdateWrapper<>();
        updateMenuWrapper.eq(Permission::getId,permissionId).or()
                        .eq(Permission::getParentId,permissionId);
        updateMenuWrapper.set(Permission::getIsDelete,BaseConstants.DELETED);
        PermissionService permissionService = (PermissionService) AopContext.currentProxy();
        permissionService.update(updateMenuWrapper);
        //删除menu -role关系
        return rolePermissionService.deletePermissionRoleByPermissionIds(roleMenuIds);
    }

    private List<RoleBindPermissionVo> buildRoleMenuTree(List<Permission> permissions, Integer parentId) {
        return permissions.stream()
                .filter(permission -> permission.getParentId().equals(parentId))
                .map(permission -> {
                    RoleBindPermissionVo roleBindPermissionVo = new RoleBindPermissionVo();
                    BeanUtils.copyProperties(permission, roleBindPermissionVo);
                    roleBindPermissionVo.setChildren(buildRoleMenuTree(permissions, permission.getId()));
                    return roleBindPermissionVo;
                })
                .collect(Collectors.toList());
    }

    @Override
    public List<String> getPermissionListByRoleIds(List<Integer> roleId) {

        return null;
    }

    private List<PermissionVo> buildMenuTree(List<Permission> permissions, Integer parentId) {
        return permissions.stream()
                .filter(permission -> permission.getParentId().equals(parentId))
                .map(permission -> {
                    PermissionVo permissionVo = new PermissionVo();
                    BeanUtils.copyProperties(permission, permissionVo);
                    permissionVo.setChildren(buildMenuTree(permissions, permission.getId()));
                    return permissionVo;
                })
                .collect(Collectors.toList());
    }

}

